package com.exercise.AndroidCamera;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Timer;
import java.util.TimerTask;

import android.content.ContentValues;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Face;
import android.hardware.Camera.FaceDetectionListener;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore;
import android.provider.MediaStore.Images.Media;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.telpoo.frame.delegate.Idelegate;
import com.telpoo.frame.model.BaseModel;
import com.telpoo.frame.net.BaseNetSupportBeta;
import com.telpoo.frame.net.NetConfig;
import com.telpoo.frame.object.BaseObject;
import com.telpoo.frame.ui.BaseActivity;
import com.telpoo.frame.utils.Mlog;

public class AndroidCamera extends BaseActivity implements
		SurfaceHolder.Callback {
	Timer timer;
	Camera camera;
	SurfaceView surfaceView;
	SurfaceHolder surfaceHolder;
	boolean previewing = false;
	LayoutInflater controlInflater = null;

	Button buttonTakePicture;
	TextView prompt;

	//DrawingView drawingView;
	Face[] detectedFaces;
	Face[] currentFaces;
	ImageView img;
	final int RESULT_SAVEIMAGE = 0;

	Handler handler;
	Runnable runnable;
	private boolean isChecking = false;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		img = (ImageView) findViewById(R.id.img);
		
		/*
		Thread t = new Thread() {

			@Override
			public void run() {
				try {
					while (!isInterrupted()) {
						Thread.sleep(2000);
						runOnUiThread(new Runnable() {

							@Override
							public void run() {
								Mlog.T("ré");

								if (detectedFaces != null
										&& detectedFaces.length > 0) {
									if (currentFaces == null)
										currentFaces = detectedFaces; // first
																		// time

									if (!isChecking) {

										if (!distance(currentFaces,
												detectedFaces)) {
											try {
												capture();
											} catch (Exception e) {

											}
											isChecking = true;
										}

									}

									currentFaces = detectedFaces;
								}

							}

						});
					}
				} catch (InterruptedException e) {
				}
			}
		};

		t.start();
		*/
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
		Mlog.isLog = true;
		BaseNetSupportBeta.getInstance().init(new NetConfig.Builder().build());
		getWindow().setFormat(PixelFormat.UNKNOWN);
		surfaceView = (SurfaceView) findViewById(R.id.camerapreview);
		surfaceHolder = surfaceView.getHolder();
		surfaceHolder.addCallback(this);
		//surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

//		drawingView = new DrawingView(this);
//		LayoutParams layoutParamsDrawing = new LayoutParams(
//				LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
//		this.addContentView(drawingView, layoutParamsDrawing);

		controlInflater = LayoutInflater.from(getBaseContext());
		View viewControl = controlInflater.inflate(R.layout.control, null);
		LayoutParams layoutParamsControl = new LayoutParams(
				LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
		this.addContentView(viewControl, layoutParamsControl);

		buttonTakePicture = (Button) findViewById(R.id.takepicture);
		buttonTakePicture.setOnClickListener(new Button.OnClickListener() {

			@Override
			public void onClick(View arg0) {

				capture();
			}
		});

//		LinearLayout layoutBackground = (LinearLayout) findViewById(R.id.background);
//		layoutBackground.setOnClickListener(new LinearLayout.OnClickListener() {
//
//			@Override
//			public void onClick(View arg0) {
//
//				buttonTakePicture.setEnabled(false);
//				camera.autoFocus(myAutoFocusCallback);
//			}
//		});

		prompt = (TextView) findViewById(R.id.prompt);
	}

	protected void capture() {

//		AudioManager mgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
//		mgr.setStreamMute(AudioManager.STREAM_SYSTEM, true);

		camera.takePicture(myShutterCallback, myPictureCallback_RAW,
				myPictureCallback_JPG);

		final Handler handler = new Handler();
		Timer t = new Timer();
		t.schedule(new TimerTask() {
			public void run() {
				handler.post(new Runnable() {
					public void run() {
						AudioManager mgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
						mgr.setStreamMute(AudioManager.STREAM_SYSTEM, false);
					}
				});
			}
		}, 1000);

	}

//	FaceDetectionListener faceDetectionListener = new FaceDetectionListener() {
//
//		@Override
//		public void onFaceDetection(Face[] faces, Camera camera) {
//
//			if (faces.length == 0) {
//				prompt.setText(" No Face Detected! ");
//				drawingView.setHaveFace(false);
//			} else {
//				prompt.setText(String.valueOf(faces.length) + " Face Detected ");
//				drawingView.setHaveFace(true);
//				detectedFaces = faces;
//				drawingView.setFace(faces);
//
//			}
//
//			drawingView.invalidate();
//
//		}
//	};

	AutoFocusCallback myAutoFocusCallback = new AutoFocusCallback() {

		@Override
		public void onAutoFocus(boolean arg0, Camera arg1) {

			buttonTakePicture.setEnabled(true);
		}
	};

	private boolean distance(Face[] currentFaces, Face[] detectedFaces) {

		if (Math.abs(currentFaces[0].rect.left - detectedFaces[0].rect.left) > 20)
			return true;

		if (Math.abs(currentFaces[0].rect.top - detectedFaces[0].rect.top) > 20)
			return true;
		if (Math.abs(currentFaces[0].rect.right - detectedFaces[0].rect.right) > 20)
			return true;

		if (Math.abs(currentFaces[0].rect.bottom - detectedFaces[0].rect.bottom) > 20)
			return true;
		return false;

	}

	ShutterCallback myShutterCallback = new ShutterCallback() {

		@Override
		public void onShutter() {

		}
	};

	PictureCallback myPictureCallback_RAW = new PictureCallback() {

		@Override
		public void onPictureTaken(byte[] arg0, Camera arg1) {

		}
	};

	PictureCallback myPictureCallback_JPG = new PictureCallback() {

		@Override
		public void onPictureTaken(byte[] arg0, Camera arg1) {

			Bitmap bitmapPicture = BitmapFactory.decodeByteArray(arg0, 0,
					arg0.length);
			
			img.setVisibility(View.VISIBLE);
			img.setImageBitmap(bitmapPicture);
			
			
			/*
			int vWidth = bitmapPicture.getWidth();
			int vHeight = bitmapPicture.getHeight();

			int l = detectedFaces[0].rect.left;	
			int t = detectedFaces[0].rect.top;
			int r = detectedFaces[0].rect.right;
			int b = detectedFaces[0].rect.bottom;
			int left = (l + 1000) * vWidth / 2000;
			int top = (t + 1000) * vHeight / 2000;
			int right = (r + 1000) * vWidth / 2000;
			int bottom = (b + 1000) * vHeight / 2000;

			if (left - 50 > 0)
				left = left - 50;

			if (right - 50 > 0)
				right = right - 50;

			if (right + 1000 < vWidth)
				right = right + 50;
			else
				right = vWidth;

			if (bottom + 1000 < vHeight)
				bottom = bottom + 50;
			else
				bottom = vHeight;

			Bitmap result = Bitmap.createBitmap(bitmapPicture, left, top,
					Math.abs(left - right), Math.abs(top - bottom));
			bitmapPicture.recycle();

			img.setVisibility(View.VISIBLE);
			img.setImageBitmap(result);

			Uri uriTarget = getContentResolver().insert(
					Media.EXTERNAL_CONTENT_URI, new ContentValues());

			OutputStream imageFileOS;
			try {
				imageFileOS = getContentResolver().openOutputStream(uriTarget);
				imageFileOS.write(arg0);
				imageFileOS.flush();
				imageFileOS.close();
				TextView tv = (TextView) findViewById(R.id.temp);
				tv.setText("Image saved: " + uriTarget.toString());

			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}

			camera.startPreview();
			camera.startFaceDetection();

			File f = new File(uriTarget.toString());
			Mlog.T("path=" + f.getPath());
			// TODO

			getinfo(getPath(uriTarget));
		*/
		}
	};

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {

		if (previewing) {
			if(camera!=null){
				camera.stopFaceDetection();
				camera.stopPreview();
			}
			previewing = false;
		}

		if (camera != null) {
			try {
				camera.setPreviewDisplay(surfaceHolder);
				camera.startPreview();

				prompt.setText(String.valueOf("Max Face: "
						+ camera.getParameters().getMaxNumDetectedFaces()));
				camera.startFaceDetection();
				previewing = true;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	protected void getinfo(String path) {

		BaseModel model = new BaseModel() {
			public void onSuccess(int taskType, java.util.ArrayList<?> list,
					String msg) {
				BaseObject oj = (BaseObject) list.get(0);
				detectedFaces = null;
				currentFaces = null;
				ContentValues vl = oj.getParams();

				Iterator<?> keys = vl.keySet().iterator();
				String cong = "";

				while (keys.hasNext()) {
					String key = keys.next().toString();

					String value = vl.getAsString(key);

					if (!value.contains("{"))
						cong += key + ":" + value + "\n";

				}

				img.setVisibility(View.GONE);
				MyUtils.dialog(AndroidCamera.this, cong, new Idelegate() {

					@Override
					public void callBack(Object value, int where) {
						isChecking = false;

					}
				});

				closeProgressDialog();

			};

			public void onFail(int taskType, String msg) {
				showToast("" + msg);
				detectedFaces = null;
				currentFaces = null;
				img.setVisibility(View.GONE);
				closeProgressDialog();
				isChecking = false;
			};
		};

		ArrayList<String> list = new ArrayList<String>();
		list.add(path);
		Task task = new Task(model, TaskType.TASK_RECOGNITION, list,
				getBaseContext());
		task.exe();

		showProgressDialog(AndroidCamera.this);

	}

	public String getPath(Uri uri) {
		String[] projection = { MediaStore.Images.Media.DATA };
		Cursor cursor = managedQuery(uri, projection, null, null, null);
		int column_index = cursor
				.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
		cursor.moveToFirst();
		return cursor.getString(column_index);
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {

		boolean haveFrontCamera = false;

		int numCameras = Camera.getNumberOfCameras();
		
		showToast("number of camera:"+numCameras);
		
		for (int i = 0; i < numCameras; i++) {
			Camera.CameraInfo info = new CameraInfo();
			Camera.getCameraInfo(i, info);
			if (CameraInfo.CAMERA_FACING_FRONT == info.facing) {
				haveFrontCamera = true;
			}

		}
		
		
		if (numCameras == 0) {
			showToast("no camera found");
			finish();
		}
		try {

			if (!haveFrontCamera) {
				showToast("No front camera available!");
				camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
			} else
				camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);

			if (camera == null) {
				showToast("no camera avaiable");
				finish();
			}
		} catch (Exception e) {
			showToast("can't open camera");
			finish();
		}

		//camera.setFaceDetectionListener(faceDetectionListener);
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {

		if (camera != null) {
			camera.stopFaceDetection();
			camera.stopPreview();
			camera.release();
			camera = null;
			previewing = false;

		}
	}

}